<html>
<head><meta charset="utf-8"><title>different assembly const A = / let A = String::new() · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/different.20assembly.20const.20A.20.3D.20.2F.20let.20A.20.3D.20String.3A.3Anew().html">different assembly const A = / let A = String::new()</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="211197176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/different%20assembly%20const%20A%20%3D%20/%20let%20A%20%3D%20String%3A%3Anew%28%29/near/211197176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matthiaskrgr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/different.20assembly.20const.20A.20.3D.20.2F.20let.20A.20.3D.20String.3A.3Anew().html#211197176">(Sep 24 2020 at 22:28)</a>:</h4>
<p>I made two functions, one returns a String::new() with a let binding and another one returns a String::new() with a const binding</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">const_string</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nb">String</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">const</span><span class="w"> </span><span class="n">A</span>: <span class="nb">String</span> <span class="o">=</span><span class="w"> </span><span class="nb">String</span>::<span class="n">new</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="n">A</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>


<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">noconst_string</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nb">String</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w">  </span><span class="nb">String</span>::<span class="n">new</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>Why is there different code generated? <span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span> <br>
<a href="https://rust.godbolt.org/z/nWP63z">https://rust.godbolt.org/z/nWP63z</a></p>



<a name="211198264"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/different%20assembly%20const%20A%20%3D%20/%20let%20A%20%3D%20String%3A%3Anew%28%29/near/211198264" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/different.20assembly.20const.20A.20.3D.20.2F.20let.20A.20.3D.20String.3A.3Anew().html#211198264">(Sep 24 2020 at 22:41)</a>:</h4>
<div class="codehilite"><pre><span></span><code>playground::const_string:
    movq    %rdi, %rax
    movq    .L__unnamed_1+16(%rip), %rcx
    movq    %rcx, 16(%rdi)
    movups  .L__unnamed_1(%rip), %xmm0
    movups  %xmm0, (%rdi)
    retq

playground::noconst_string:
    movq    %rdi, %rax
    movq    $1, (%rdi)
    xorps   %xmm0, %xmm0
    movups  %xmm0, 8(%rdi)
    retq

.L__unnamed_1:
    .asciz  &quot;\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&quot;
</code></pre></div>


<p>For the lazy like me</p>



<a name="211217231"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/different%20assembly%20const%20A%20%3D%20/%20let%20A%20%3D%20String%3A%3Anew%28%29/near/211217231" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> kennytm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/different.20assembly.20const.20A.20.3D.20.2F.20let.20A.20.3D.20String.3A.3Anew().html#211217231">(Sep 25 2020 at 04:25)</a>:</h4>
<p>LLVM IR:</p>
<div class="codehilite" data-code-language="LLVM"><pre><span></span><code><span class="vg">@0</span> <span class="p">=</span> <span class="k">private</span> <span class="k">unnamed_addr</span> <span class="k">constant</span> <span class="p">&lt;{</span> <span class="p">[</span><span class="m">24</span> <span class="k">x</span> <span class="k">i8</span><span class="p">]</span> <span class="p">}&gt;</span> <span class="p">&lt;{</span> <span class="p">[</span><span class="m">24</span> <span class="k">x</span> <span class="k">i8</span><span class="p">]</span> <span class="k">c</span><span class="s">"\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"</span> <span class="p">}&gt;,</span> <span class="k">align</span> <span class="m">8</span>

<span class="c">; playground::const_string</span>
<span class="c">; Function Attrs: nounwind nonlazybind uwtable</span>
<span class="k">define</span> <span class="k">void</span> <span class="vg">@_ZN10playground12const_string17hb89a864b3fed2ca7E</span><span class="p">(</span><span class="nv">%"std::string::String"</span><span class="p">*</span> <span class="k">noalias</span> <span class="k">nocapture</span> <span class="k">sret</span> <span class="k">dereferenceable</span><span class="p">(</span><span class="m">24</span><span class="p">)</span> <span class="nv nv-Anonymous">%0</span><span class="p">)</span> <span class="k">unnamed_addr</span> <span class="vg">#0</span> <span class="p">{</span>
<span class="nl">start:</span>
  <span class="nv nv-Anonymous">%1</span> <span class="p">=</span> <span class="k">bitcast</span> <span class="nv">%"std::string::String"</span><span class="p">*</span> <span class="nv nv-Anonymous">%0</span> <span class="k">to</span> <span class="k">i8</span><span class="p">*</span>
  <span class="k">tail</span> <span class="k">call</span> <span class="k">void</span> <span class="vg">@llvm.memcpy.p0i8.p0i8.i64</span><span class="p">(</span><span class="k">i8</span><span class="p">*</span> <span class="k">nonnull</span> <span class="k">align</span> <span class="m">8</span> <span class="k">dereferenceable</span><span class="p">(</span><span class="m">24</span><span class="p">)</span> <span class="nv nv-Anonymous">%1</span><span class="p">,</span> <span class="k">i8</span><span class="p">*</span> <span class="k">nonnull</span> <span class="k">align</span> <span class="m">8</span> <span class="k">dereferenceable</span><span class="p">(</span><span class="m">24</span><span class="p">)</span> <span class="k">getelementptr</span> <span class="k">inbounds</span> <span class="p">(&lt;{</span> <span class="p">[</span><span class="m">24</span> <span class="k">x</span> <span class="k">i8</span><span class="p">]</span> <span class="p">}&gt;,</span> <span class="p">&lt;{</span> <span class="p">[</span><span class="m">24</span> <span class="k">x</span> <span class="k">i8</span><span class="p">]</span> <span class="p">}&gt;*</span> <span class="vg">@0</span><span class="p">,</span> <span class="k">i64</span> <span class="m">0</span><span class="p">,</span> <span class="k">i32</span> <span class="m">0</span><span class="p">,</span> <span class="k">i64</span> <span class="m">0</span><span class="p">),</span> <span class="k">i64</span> <span class="m">24</span><span class="p">,</span> <span class="k">i1</span> <span class="k">false</span><span class="p">)</span>
  <span class="k">ret</span> <span class="k">void</span>
<span class="p">}</span>

<span class="c">; playground::noconst_string</span>
<span class="c">; Function Attrs: nounwind nonlazybind uwtable writeonly</span>
<span class="k">define</span> <span class="k">void</span> <span class="vg">@_ZN10playground14noconst_string17hfb4d262f952a04e4E</span><span class="p">(</span><span class="nv">%"std::string::String"</span><span class="p">*</span> <span class="k">noalias</span> <span class="k">nocapture</span> <span class="k">sret</span> <span class="k">dereferenceable</span><span class="p">(</span><span class="m">24</span><span class="p">)</span> <span class="nv">%x</span><span class="p">)</span> <span class="k">unnamed_addr</span> <span class="vg">#1</span> <span class="p">{</span>
<span class="nl">start:</span>
  <span class="nv">%_1.sroa.0.0..sroa_idx.i</span> <span class="p">=</span> <span class="k">getelementptr</span> <span class="k">inbounds</span> <span class="nv">%"std::string::String"</span><span class="p">,</span> <span class="nv">%"std::string::String"</span><span class="p">*</span> <span class="nv">%x</span><span class="p">,</span> <span class="k">i64</span> <span class="m">0</span><span class="p">,</span> <span class="k">i32</span> <span class="m">0</span><span class="p">,</span> <span class="k">i64</span> <span class="m">0</span>
  <span class="k">store</span> <span class="k">i64</span> <span class="m">1</span><span class="p">,</span> <span class="k">i64</span><span class="p">*</span> <span class="nv">%_1.sroa.0.0..sroa_idx.i</span><span class="p">,</span> <span class="k">align</span> <span class="m">8</span><span class="p">,</span> <span class="nv">!alias.scope</span> <span class="nv nv-Anonymous">!2</span>
  <span class="nv">%_1.sroa.4.0..sroa_idx.i</span> <span class="p">=</span> <span class="k">getelementptr</span> <span class="k">inbounds</span> <span class="nv">%"std::string::String"</span><span class="p">,</span> <span class="nv">%"std::string::String"</span><span class="p">*</span> <span class="nv">%x</span><span class="p">,</span> <span class="k">i64</span> <span class="m">0</span><span class="p">,</span> <span class="k">i32</span> <span class="m">1</span><span class="p">,</span> <span class="k">i32</span> <span class="m">1</span><span class="p">,</span> <span class="k">i32</span> <span class="m">1</span>
  <span class="nv">%_1.sroa.4.0..sroa_cast.i</span> <span class="p">=</span> <span class="k">bitcast</span> <span class="k">i64</span><span class="p">*</span> <span class="nv">%_1.sroa.4.0..sroa_idx.i</span> <span class="k">to</span> <span class="k">i8</span><span class="p">*</span>
  <span class="k">tail</span> <span class="k">call</span> <span class="k">void</span> <span class="vg">@llvm.memset.p0i8.i64</span><span class="p">(</span><span class="k">i8</span><span class="p">*</span> <span class="k">nonnull</span> <span class="k">align</span> <span class="m">8</span> <span class="k">dereferenceable</span><span class="p">(</span><span class="m">16</span><span class="p">)</span> <span class="nv">%_1.sroa.4.0..sroa_cast.i</span><span class="p">,</span> <span class="k">i8</span> <span class="m">0</span><span class="p">,</span> <span class="k">i64</span> <span class="m">16</span><span class="p">,</span> <span class="k">i1</span> <span class="k">false</span><span class="p">)</span> <span class="vg">#4</span><span class="p">,</span> <span class="nv">!alias.scope</span> <span class="nv nv-Anonymous">!2</span>
  <span class="k">ret</span> <span class="k">void</span>
<span class="p">}</span>
</code></pre></div>

<p>the const one becomes a memcpy off a global <code>@0</code> and the non-const one is a memset. maybe llvm is unwilling to "inline" the memcpy.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>